package interview.redisLock;

import lombok.extern.slf4j.Slf4j;
import lombok.val;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;

/**
 * @Author: zhangrongqing
 * @Date: 2019/11/21 11:01
 */
@Slf4j
public class RedisLock {
    private String Lock_Key = "redis_lock";

    long lockReleaseTime = 3000;

    private long timeout = 9000;

    SetParams params = SetParams.setParams().nx().px(lockReleaseTime);


    private static JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);

    public boolean lock(String id) {
        Jedis jedis = jedisPool.getResource();
        Long startTime = System.currentTimeMillis();
        try {
            while (true) {
                String lock = jedis.set(Lock_Key, id, params);
                if ("OK".equals(lock)) {
                    System.out.println("lockkey: " + id + " lock success");
                    return true;
                }
                Long endTime = System.currentTimeMillis();
                if (endTime - startTime > timeout) {
                    System.out.println("lockkey: " + id + " lock falied,timeout");
                    return false;
                }

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } finally {
            jedis.close();
        }
    }

    public boolean unlock(String id) {
        Jedis jedis = jedisPool.getResource();
        String script =
                "if redis.call('get',KEYS[1]) == ARGV[1] then" +
                        "   return redis.call('del',KEYS[1]) " +
                        "else" +
                        "   return 0 " +
                        "end";
        try {
            Object result = jedis.eval(script, Collections.singletonList(Lock_Key),
                    Collections.singletonList(id));
            if ("1".equals(result.toString())) {
                return true;
            }
            return false;
        } finally {
            jedis.close();
        }

    }
}
